package edu.mbb.netty.service;

import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;

import edu.mbb.netty.client.RpcRequestEntity;
import io.netty.bootstrap.ServerBootstrap;
import io.netty.channel.ChannelHandlerContext;
import io.netty.channel.ChannelInitializer;
import io.netty.channel.SimpleChannelInboundHandler;
import io.netty.channel.nio.NioEventLoopGroup;
import io.netty.channel.socket.nio.NioServerSocketChannel;
import io.netty.channel.socket.nio.NioSocketChannel;
import io.netty.handler.codec.serialization.ClassResolvers;
import io.netty.handler.codec.serialization.ObjectDecoder;
import io.netty.handler.codec.serialization.ObjectEncoder;

public class RpcService {
	public static void main(String[] args) {
		ServerBootstrap serverBootstrap = new ServerBootstrap();

		NioEventLoopGroup boos = new NioEventLoopGroup();
		NioEventLoopGroup worker = new NioEventLoopGroup();
		serverBootstrap.group(boos, worker).channel(NioServerSocketChannel.class)
				.childHandler(new ChannelInitializer<NioSocketChannel>() {
					protected void initChannel(NioSocketChannel ch) {
						ch.pipeline().addLast(new ObjectDecoder(1024 * 1024,
								ClassResolvers.weakCachingConcurrentResolver(this.getClass().getClassLoader())));
						ch.pipeline().addLast(new ObjectEncoder());
						ch.pipeline().addLast(new SimpleChannelInboundHandler<Object>() {
							@Override
							protected void channelRead0(ChannelHandlerContext ctx, Object msg)
									throws IllegalAccessException, IllegalArgumentException, InvocationTargetException,
									NoSuchMethodException, SecurityException {
								System.out.println(msg);
								RpcRequestEntity rpcRequestEntity = (RpcRequestEntity) msg;
								// 通过接口获取对应的实现类
								Class<?> interfaceClass = rpcRequestEntity.getInterfaceClass();
								// 从ioc容器中遍历
								Class<?>[] interfaces = TestServiceImpl.class.getInterfaces();
								for (Class<?> test : interfaces) {
									if (test.equals(interfaceClass)) {
										System.out.println("--------------");
										TestServiceImpl tests = new TestServiceImpl();
										String methodName = rpcRequestEntity.getMethodName();
										Object[] args2 = rpcRequestEntity.getArgs();
										Class<?>[] paramTypes = rpcRequestEntity.getParamTypes();
										Method declaredMethod = TestServiceImpl.class.getDeclaredMethod(methodName,
												paramTypes);
										Object invoke = declaredMethod.invoke(tests, args2);
										ctx.write(invoke);
										ctx.flush();
									}
								}

							}
						});
					}
				}).bind("127.0.0.1", 8080);
	}
}
